#!/usr/bin/env/python

import socket
import select
import gobject
import threading
import gtk
import urllib
import os
import sys

import dp

class Window:

	def __init__(self, main_window):	
		self.main_window = main_window
		self.window = gtk.Window()
		self.window.set_size_request(500, 500)
		self.window.connect("destroy", self.quit)
		self.box = gtk.VBox(False, 0)

		self.chat_tree = gtk.TreeView()

		self.notebook = gtk.Notebook()
		self.notebook.connect("switch-page", self.changed_tab)
		self.notebook.set_scrollable(True)
		self.notebook.set_homogeneous_tabs(True)
		self.open_tabs = {}
		self.shown = 0

		self.window.add(self.box)

		self.chat_window()


	def quit(self, window):
		self.created = 0
		self.window.destroy()

	def chat_window(self):
		top_box = gtk.HBox(False, 0)

		add_box = gtk.VBox(False, 1)
		add_btn = gtk.Button("Invite")
		add_pb =  self.chat_tree.render_icon(gtk.STOCK_ADD, gtk.ICON_SIZE_BUTTON)
		add_img = gtk.Image()
		add_img.set_from_pixbuf(add_pb)
		add_btn.set_relief(gtk.RELIEF_NONE)
		add_btn.connect("clicked", self.invite)
		add_box.pack_start(add_img, False, False, 0)
		add_box.pack_start(add_btn, False, False, 0)

		block_box = gtk.VBox(False, 1)
		block_pb =  self.chat_tree.render_icon(gtk.STOCK_STOP, gtk.ICON_SIZE_BUTTON)
		block_btn = gtk.Button("Block")
		block_btn.set_relief(gtk.RELIEF_NONE)
		block_img = gtk.Image()
		block_img.set_from_pixbuf(block_pb)
		block_btn.set_relief(gtk.RELIEF_NONE)
		block_btn.connect("clicked", self.block)
		block_box.pack_start(block_img, False, False, 0)
		block_box.pack_start(block_btn, False, False, 0)

		send_box = gtk.VBox(False, 1)
		send_pb =  self.chat_tree.render_icon(gtk.STOCK_GO_FORWARD, gtk.ICON_SIZE_BUTTON)
		send_btn = gtk.Button("Send")
		send_btn.set_relief(gtk.RELIEF_NONE)
		send_img = gtk.Image()
		send_img.set_from_pixbuf(send_pb)
		send_btn.set_relief(gtk.RELIEF_NONE)
		send_box.pack_start(send_img, False, False, 0)
		send_box.pack_start(send_btn, False, False, 0)



		dpbox = gtk.VBox(False, 1)
		dppb =  self.chat_tree.render_icon(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_BUTTON)
		dpbtn = gtk.ToggleButton("Display Pictures")
		dpbtn.connect("toggled", self.show_dp)
		dpbtn.set_relief(gtk.RELIEF_NONE)
		dpimg = gtk.Image()
		dpimg.set_from_pixbuf(dppb)
		dpbtn.set_relief(gtk.RELIEF_NONE)
		dpbox.pack_start(dpimg, False, False, 0)
		dpbox.pack_start(dpbtn, False, False, 0)

		top_box.pack_start(add_box, False, False, 10)
		top_box.pack_start(block_box, False, False, 10)
		top_box.pack_start(send_box, False, False, 10)
		top_box.pack_start(dpbox, False, False, 10)
		top_box.show()
		

		self.box.pack_start(top_box, False, True, 0)
		self.box.pack_start(self.notebook, True, True)

		self.created = 1

	def add_tab(self, tab, user_email):
		if self.created:
				l = gtk.Label(user_email)
				page = self.notebook.append_page(tab, l)
				self.open_tabs[user_email] = page

		else:
			self.__init__(self.main_window) #If window is closed, re-init the class
							#to create all variables needed
			l = gtk.Label(user_email)
			page = self.notebook.append_page(tab, l)
			self.open_tabs[user_email] = page


		self.notebook.set_current_page(page)
		self.notebook.queue_draw_area(0,0,-1,-1)			


	def switch_page(self, user_email):
		page = self.open_tabs[user_email]
		self.notebook.set_current_page(page)

	def show_window(self):
		self.window.show_all()
		self.shown = 1


	def rem_tab(self):
		page = self.notebook.get_current_page()
		self.notebook.remove_page(page)
		self.notebook.queue_draw_area(0,0,-1,-1)

	def changed_tab(self, notebook, page, page_num):
		tab = notebook.get_nth_page(page_num)
		label = notebook.get_tab_label(tab).get_label()
		if '<span foreground="#FF0000">' in label:
			strip_label = label[27:-7]
		elif '<span foreground="#00A800">' in label:
			strip_label = label[27:-7]

		else:
			strip_label = label

		new_label = gtk.Label(strip_label)
		notebook.set_tab_label(tab, new_label)

	def notify_typing(self, user_email):
		user_page = self.open_tabs[user_email]
		tab = self.notebook.get_nth_page(user_page)
		label = self.notebook.get_tab_label(tab)
		label.set_markup('<span foreground="#00A800">' + user_email + '</span>')
		label.set_use_markup(True)
		self.notebook.set_tab_label(tab, label)

	def remove_markup(self, user_email=None, page=None):
		if user_email is not None:
			user_page = self.open_tabs[user_email]
			tab = self.notebook.get_nth_page(user_page)
		elif page is not None:
			tab = self.notebook.get_nth_page(page)

		label = self.notebook.get_tab_label(tab).get_label()
		strip_label = label[27:-7]
		new_label = gtk.Label(strip_label)
		self.notebook.set_tab_label(tab, new_label)

	def notify_new(self, user_email):
		#self.remove_markup(user_email)
		user_page = self.open_tabs[user_email]
		tab = self.notebook.get_nth_page(user_page)
		label = self.notebook.get_tab_label(tab)
		label.set_markup('<span foreground="#FF0000">' + user_email + '</span>')
		label.set_use_markup(True)
		self.notebook.set_tab_label(tab, label)

	def show_dp(self, t_button):
		page = self.notebook.get_current_page()
		tab = self.notebook.get_nth_page(page)
		label = self.notebook.get_tab_label(tab)
		email = label.get_text()
		print email, tab
		if t_button.get_active():
			self.window.set_size_request(550, 500)
			self.dp_box.show()
		elif not t_button.get_active():
			self.dp_box.hide()	
			self.window.set_size_request(500, 500)


	def create_online_users(self, session):
		invite_user_dialog = gtk.Dialog("Add Contact", self.window, 0, buttons=None)
		invite_user_dialog.set_size_request(100, 200)
		online_users = gtk.TreeStore(str)
		for user in	self.main_window.m.online_users.keys():
			online_users.append(None, [user])

		col = gtk.TreeViewColumn()
		cell = gtk.CellRendererText()
		col.pack_start(cell, True)
		col.add_attribute(cell, 'text', 0)

		online_tree = gtk.TreeView(online_users)
		online_tree.connect("row-activated", self.invite_user, online_users, session)
		online_tree.append_column(col)

		sc_w = gtk.ScrolledWindow()
		sc_w.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		sc_w.set_size_request(-1,100)
		sc_w.add(online_tree)

		invite_user_btn = gtk.Button("Cancel")

		invite_user_dialog.vbox.pack_start(sc_w, True, True, 0)
		invite_user_dialog.vbox.pack_start(invite_user_btn, False, False, 0)
		invite_user_dialog.show_all()


	def invite(self, button):
		page = self.notebook.get_current_page()
		box = self.notebook.get_nth_page(page)
		label = self.notebook.get_tab_label(box)
		email = label.get_label()
		#users = self.main_window.open_chats[email]
		session =  self.main_window.open_chats[email]
		self.create_online_users(session)
		

	def invite_user(self, treeview, path, view_column, store, session):
		"""User double clicks on a user to invite him to chat"""
		t_iter = store.get_iter(path) #Return the iter of the buddy
		email = store.get_value(t_iter,0) #Retrieve their email from the hidden column
		session.parse_sync("CAL", email)

	def block(self, button):
		page = self.notebook.get_current_page()
		box = self.notebook.get_nth_page(page)
		label = self.notebook.get_tab_label(box)
		email = label.get_label()
		#users = self.main_window.open_chats[email]
		session =  self.main_window.open_chats[email]
		session.socket.send("REM "+str(session.tr_id)+" AL "+email+"\r\n")
		session.socket.send("ADD "+str(session.tr_id)+" BL "+email+" "+email+"\r\n")

class Tab:

	def __init__(self, user_instance, switchboard, chat_window):
		self.user = user_instance
		self.switchboard = switchboard
		self.chat_window = chat_window

		self.to_send = ''
		self.typing = 0

		
		self.chat_tree = gtk.TreeView()
		self.chat_tree.connect("destroy", self.quitting)
		self.online_img = self.chat_tree.render_icon(gtk.STOCK_YES, gtk.ICON_SIZE_DND)
		self.dpbox = gtk.VBox(False, 1)
		self.dp_box = gtk.VBox(False, 0)
		edir = os.path.dirname(__file__) or sys.path[0]
		edir += "/emoticons/"
		self.emos = {":)": edir+"regular_smile.gif",
					";)": edir+"wink_smile.gif",
					":D": edir+"teeth_smile.gif",
					":|": edir+"what_smile.gif",
					":p": edir+"tongue_smile.gif",
					"(Y)": edir+"thumbs_up.gif",
					"(N)": edir+"thumbs_down.gif",
					"(*)": edir+"star.gif",
					"(H)": edir+"shades_smile.gif",
					":(": edir+"sad_smile.gif",
					"(F)": edir+"rose.gif",
					":$": edir+"red_smile.gif",
					":o": edir+"omg_smile.gif",
					"(8)": edir+"note.gif",
					"(S)": edir+"moon.gif",
					"(I)": edir+"lightbulb.gif",
					"(k)": edir+"kiss.gif",
					"(l)": edir+"heart.gif",
					"({)": edir+"guy_hug.gif",
					"(})": edir+"girl_hug.gif",
					"(6)": edir+"devil_smile.gif",
					":'(": edir+"cry_smile.gif",
					":s": edir+"confused_smile.gif",
					"(U)": edir+"broken_heart.gif",
					":@": edir+"angry_smile.gif",
					"(A)": edir+"angel_smile.gif",
					"^o)": edir+"50_50.gif",
					":-#": edir+"47_47.gif",
					"+o(": edir+"52_52.gif",
					"*-)": edir+"75_75.gif"
					}

	def create(self):
		box = gtk.VBox(False, 0)

		user_box = gtk.HBox(False, 5)
		nick_n = gtk.Label("To: "+self.user.nick)
		email = gtk.Label("<"+self.user.email+">")

		close_box = gtk.EventBox()
		close_pb =  self.chat_tree.render_icon(gtk.STOCK_CANCEL, gtk.ICON_SIZE_MENU)
		close_img = gtk.Image()
		close_img.set_from_pixbuf(close_pb)
		close_box.add(close_img)
		close_box.set_events(gtk.gdk.BUTTON_PRESS_MASK)
		close_box.connect("button_press_event", self.close_tab)

		user_box.pack_start(nick_n, False, True, 0)
		user_box.pack_start(email, False, True, 0)
		user_box.pack_end(close_box, False, False, 0)

		table = gtk.TextTagTable()
		mid_box = gtk.HBox()
		self.textbuffer = gtk.TextBuffer()
		self.textbuffer.connect("insert-text", self.typing_text)
		self.text = gtk.TextView(self.textbuffer)
		scroll_w= gtk.ScrolledWindow()
		scroll_w.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		scroll_w.add(self.text)
		mid_box.pack_start(scroll_w)

		self.dp_box.set_size_request(50, 500)
		dpb =  self.chat_tree.render_icon(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_BUTTON)
		dimg = gtk.Image()
		dimg.set_from_pixbuf(dpb)
		dimg.show()
		self.dp_box.pack_start(dimg, False, False, 0)
		self.dp_box.set_no_show_all(True)
		mid_box.pack_end(self.dp_box, False, False)


		
		self.enter_buffer = gtk.TextBuffer(table)
		self.enter_text = gtk.TextView(self.enter_buffer)
		self.enter_text.grab_focus()
		self.enter_text.set_wrap_mode(gtk.WRAP_WORD)
		self.enter_buffer.connect_after("insert-text", self.typing_text)
		self.enter_text.show()
		sc_w = gtk.ScrolledWindow()
		sc_w.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		sc_w.set_size_request(400,40)
		sc_w.add(self.enter_text)
		

		bottom_box = gtk.HBox(False, 0)
		self.chg_color = gtk.ColorButton()
		self.chg_color.set_title("Set font color")
		self.chg_color.set_size_request(-1,27)
		self.chg_font = gtk.FontButton()
		self.chg_font.set_use_font(True)
		self.chg_font.set_size_request(-1, 27)
		bottom_box.pack_start(self.chg_color, False, False, 0)
		bottom_box.pack_start(self.chg_font, False, False, 0)


		self.cw_statusbar = gtk.Statusbar()
		self.context_id = self.cw_statusbar.get_context_id("Statusbar")
	
		box.pack_start(user_box, False, True, 3)
		box.pack_start(mid_box, True, True, 3)
		box.pack_start(bottom_box, False, False, 2)
		box.pack_start(sc_w, False, True, 0)
		box.pack_start(self.cw_statusbar, False, True, 0)
		box.show_all()

		return box

	def quitting(self, tree):
		self.switchboard.close_chat()

	def wipe_tree(self, model, path, iter_):
		model.remove(iter_)

	def close_tab(self, *args):
		self.switchboard.close_chat()
		self.chat_window.rem_tab()

	def typing_text(self,text_buf, text_iter, *args):
		end = text_buf.get_iter_at_mark(text_buf.get_insert())
		start = end.copy()
		start.backward_chars(args[1])
		if args[0] != "\n":
			self.to_send += args[0]
			if not self.typing:
				self.switchboard.typing_notification()
				self.typing = 1
		else:
			if self.send_text(self.to_send):
				self.to_send = ''
				self.typing = 0

		gtk.main_iteration()

	def typing_notification(self, user_email):
		self.chat_window.notify_typing(user_email)


	def send_text(self, text):
		print "text is "+text
		if len(text) > 0:
			previous_position = 0
			tag = self.textbuffer.create_tag()
			color = self.chg_color.get_color()
			font = self.chg_font.get_font_name()
			tag.set_property("font", font)
			tag.set_property("foreground-gdk", color)	

			if len(text) > 50:
				text = self.create_wrap(text)

			self.switchboard.send_text(text, font, color)
			self.enter_buffer.set_text('')

			ei = self.textbuffer.get_end_iter()
			self.textbuffer.insert(ei, ""+self.switchboard.my_instance.nick+" says:\n")

			emoticons = self.has_emoticon(text)

			if type(emoticons) is list:
				ei = self.textbuffer.get_end_iter()
				to_emoticon = text[:emoticons[1]]
				self.textbuffer.insert(ei, to_emoticon)
				ei = self.textbuffer.get_end_iter()
				emot = self.smiley(emoticons[0])
				ei = self.textbuffer.get_end_iter()
				self.textbuffer.insert_pixbuf(ei, emot)
				ei = self.textbuffer.get_end_iter()
				rest_text = text[emoticons[1]+3:] +"\r\n"
				print rest_text
				self.textbuffer.insert(ei, rest_text)
					

			elif type(emoticons) is dict:
				for emoticon, index in emoticons.items():
					ei = self.textbuffer.get_end_iter()
					to_emoticon = text[previous_position:emoticons[1]]
					self.textbuffer.insert(ei, to_emoticon)
					ei = self.textbuffer.get_end_iter()
					emot = self.smiley(emoticon)
					ei = self.textbuffer.get_end_iter()
					self.textbuffer.insert_pixbuf(ei, emot)
					previous_position = index+2

				ei = self.textbuffer.get_end_iter()
				self.textbuffer.insert(ei, ""+"\r\n")

			else:
				ei = self.textbuffer.get_end_iter()
				self.textbuffer.insert_with_tags(ei, text+"\n", tag)


			return True



	def got_text(self, text, format):
		tag = self.textbuffer.create_tag()
		self.cw_statusbar.pop(self.context_id)

		if len(text) > 50:
			text = self.create_wrap(text)

		if len(format[2]) > 0:
			color = format[2]
			color = gtk.gdk.color_parse(color)
			tag.set_property("foreground-gdk", color)

		tag.set_property("font", format[0])

		ei = self.textbuffer.get_end_iter()
		self.textbuffer.insert(ei, ""+self.user.nick+" says:\n")
		ei = self.textbuffer.get_end_iter()
		self.textbuffer.insert_with_tags(ei, text+"\n", tag)

		current_page = self.chat_window.notebook.get_current_page()
		user_page = self.chat_window.open_tabs[self.user.email]
		if current_page != user_page:
			self.chat_window.notify_new(self.user.email)
		else:
			self.chat_window.remove_markup(user_email=self.user.email)


	def smiley(self, code):
		if code in self.emos.keys():
			emoticonpb = gtk.gdk.pixbuf_new_from_file(self.emos[code])
			return emoticonpb

	def has_emoticon(self, text):
		emoticons = {}
		for em in self.emos.keys():
				index = text.find(em)
				if index >= 0:
					print index
					emoticon = self.to_send[index:index+2]
					emoticons[emoticon] = index

		if len(emoticons) > 1:
			return emoticons
		elif len(emoticons) == 1:
			for emoticon, index in emoticons.items():
				return [emoticon, index]
		else:
			return None

	def format_text(self, format, text):
		font = format[0]
		color = format[2][::-1]
		if len(color) == 1:
			color = color.zfill(6)
		style = format[1]
		style = self.get_style(style)
		if style == "normal":
				formatted_text = "<span font_desc=\""+font+"\" foreground=\"#"+color+"\">"\
									+text+"</span>"

		elif style == "bold":
				formatted_text = "<span font_desc=\""+font+"\" foreground=\"#"+color+\
									"\" weight=\"bold\">"+text+"</span>"

		elif style == "italic":
				formatted_text = "<span font_desc=\""+font+"\" foreground=\"#"+color+\
									"\" style=\"italic\">"+text+"</span>"

		elif style == "both":
				formatted_text = "<span font_desc=\""+font+"\" foreground=\"#"+color+\
									"\" weight=\"bold\" style=\"italic\">"+text+"</span>"
		else:
			formatted_text = "<span font_desc=\""+font+"\" foreground=\"#"+color+\
									"\">"+text+"</span>"

		return formatted_text
					
	def get_style(self, style):
		if style == "B":
			return "bold"
		elif style == "I":
			return "italic"
		elif style == "BI":
			return "both"
		elif style == "":
			return 'normal'
		else:
			pass

	def create_wrap(self, long_text):
		from math import ceil
		total = ""
		total_text = long_text.split(" ")
		number_lines = len(total_text) / float(50)
		number_lines = ceil(number_lines)
		curr_index = 0
		next_index = 8
		print number_lines
		while number_lines > 0:
				part = total_text[curr_index:next_index]
				next_index += 8
				curr_index += 8
				number_lines -= 1
				print "Total is", total
				print "part is", part
				total += " ".join(part) + "\n"
				print "Total after", total
		print total
		return total


	def notify(self, msg):
		"""Notifies the user of the ongoing events.."""
		print msg
		
class Session(threading.Thread):

	def __init__(self, my_instance, chat_window,
					sess_details=None, user_instance=None, initiator=0):

		threading.Thread.__init__(self)
		self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.tr_id = 0
		self.qng = 0
		self.my_instance = my_instance
		self.my_email = my_instance.email
		self.user = user_instance
		self.sess_details = sess_details
		self.initiator = initiator
		self.running = 0
		self.gui = Tab(user_instance, self, chat_window)
		self.tab = self.gui.create()
		self.id = ''


	def read_line(self):
		"""Read one line from the server and return it"""
		character = self.socket.recv(1)		
		prev_character = ''
		received_line = ''
		while character != "\n":
			received_line = received_line + character
			prev_character = character	
			character = self.socket.recv(1)

		if character == "\n" and prev_character == "\r": 
			# check if we get an /r/n which means end of line
			received_line = received_line + character
			return received_line		

	def parse_sync(self, cmd, params=None):
		"""Send a command to the server, and wait for the response"""
		if params:
			command = cmd + ' ' + str(self.tr_id) + ' ' + params + '\r\n'
		else:
			command = cmd + ' ' + str(self.tr_id) + '\r\n'

		self.socket.send(command)
		print ">> ", repr(command)
		self.tr_id += 1
		server_answer = self.read_line()
		if server_answer:
			print "<< ", repr(server_answer)
			return server_answer

	def sync(self, command):
		"""Send a command to the server, and wait for the response
			No parsing to the command is done however."""
		if self.socket.send(command):
			print ">> ", repr(command)
			self.tr_id += 1
			server_answer = self.read_line()
			if server_answer:
				print "<< ", repr(server_answer)
				return server_answer

	def establish(self):
		xfr = self.sess_details[0]
		auth = self.sess_details[1]
		self.id = self.sess_details[2]
		self.socket.connect((xfr, 1863))
		data_in = self.parse_sync("ANS", ""+self.my_email+" "+auth+" "+self.id)

		#ugly.. receives the IRO's until we get an answer
		while data_in != "ANS":
			data_in = self.read_line().split(" ")[0]

		#Start the thread Here#
		return True

	def create(self):
		xfr = self.sess_details[0]
		auth = self.sess_details[1]
		self.socket.connect((xfr, 1863))
		usr = self.parse_sync("USR", ""+self.my_email+" "+auth).split(" ")[0]
		if usr == "USR":
			return True
		else:
			return False

	def invite(self, user_instance):
		self.parse_sync("CAL", ""+user_instance.email)
		joi = self.read_line().split(" ")[0]
		if joi == "JOI":
			self.gui.cw_statusbar.push(self.gui.context_id, "Opened Chat Session")
			return True
		else:
			return False
			
	def invited(self):
		if self.establish():
#			self._check_dp()
			self.running = 1	
			self.start()

	def inviter(self):
		if self.create():
			self.invite(self.user)
			self.running = 1
			self.start()
			self.gui.chat_window.show_window()
		

	def run(self):
		self.running = 1
		gobject.timeout_add(500, self.watch_socket)

	def watch_socket(self):
		"""Check if the server has send anything to the client, if it has
			process what we got"""
		if self.running:
			socket_descriptor = self.socket.fileno()
			read,write,error = select.select([socket_descriptor], [], [], 0)
			if len(read) > 0: #check if there is something to read
				server_data = self.read_line()
				self.process_incoming(server_data)

			return True
		

	def process_incoming(self,data):
		"""Trigger is gobject.IO_IN"""
		data_chunks = data.split(" ")
		command = data_chunks[0]

		if command == "MSG":
			payload = int(data_chunks[3][:-2])
			msg = self.socket.recv(payload)
			msg_type = msg.split("\r\n")[1].split(": ")[1]
			#just in case there is encoding or shit with the type
			msg_type = msg_type.split(" ")[0]
			if msg_type == "text/x-clientcaps":
				print "User send client details."

			elif msg_type == "text/x-msmsgscontrol":
				self.gui.cw_statusbar.push(self.gui.context_id,
											self.user.nick+" is typing...")
				self.gui.typing_notification(self.user.email)

			elif msg_type == "text/plain;" or msg_type == "text/plain":
				if not self.gui.chat_window.shown:
					self.gui.chat_window.show_window()

				msg_data = msg.split("\r\n")
				chat_key = msg_data.index('') + 1 #the split creates an empty value which
										  # separates the text from the msg header
				format_key = chat_key - 2 #: the index of the chat formatting style

				chat = self.parse_text(msg_data, chat_key)
				format_data = msg_data[format_key]
				format = self.parse_format(format_data)

				self.gui.got_text(chat, format)
				self.gui.to_send = ''

		elif command == "BYE":
			self.close_chat()

		else:
			print data_chunks

		return True


	def typing_notification(self):
		msnlp = 'MIME-Version: 1.0\r\nContent-Type: text/x-msmsgscontrol\r\nTypingUser: '
		msnlp = msnlp +self.my_email+ '\r\n\r\n'
		payload = str(len(msnlp))
		total = 'MSG '+str(self.tr_id)+' A '+payload+'\r\n'+msnlp	
		self.socket.send(total)	

	def send_text(self, text, font, color):
		import urllib
		bold = 0
		italic = 0
		font_details = font.split(" ")
		font_face = font_details[:-1]
		if "Bold" in font_face:
			font_face.remove("Bold")
			bold = 1
		if "Italic" in font_face:
			font_face.remove("Italic")
			italic = 1
		font_face = " ".join(font_face)
		font_face = urllib.quote(font_face)
		font_color = self.color_to_hex(color)

		if bold and not italic:
			ef = "B"
		elif not bold and italic:
			ef = "I"
		elif bold and italic:
			ef = "BI"

		else:
			ef = ""
		msnlp = 'MIME-Version: 1.0\r\n' \
		'Content-Type: text/plain; charset=UTF-8\r\n' \
		'X-MMS-IM-Format: FN='+font_face+'; EF='+ef+'; CO='+font_color+'; CS=0; PF=0\r\n'\
		'\r\n'\
		''+text

		payload = str(len(msnlp))
		total = 'MSG '+str(self.tr_id)+' A '+payload+'\r\n'+msnlp
		self.socket.send(total)

	def color_to_hex(self, color):
		"""Return the color of in hex format from a gdk.color
			Taken from: http://code.google.com/p/geditclassbrowser/
			source/browse/trunk/classbrowser/options.py?r=20"""
		r = str(hex( color.red / 256 ))[2:]
		g = str(hex( color.green / 256 ))[2:]
		b = str(hex( color.blue / 256 ))[2:]
		return "%s%s%s"%(b.zfill(2),g.zfill(2),r.zfill(2)) #reversed, thats how MSN does it


	def parse_text(self, msg_data, chat_key):
		chat = ''
		text = msg_data[chat_key:]
		if len(text) > 1:
			for line in text:
				chat = chat+'   '+line+'\r\n   '
		else:
			chat = "".join(text)

		chat = '   '+chat  #indent the chat under the nickname

		return chat

	def parse_format(self, format):
		"""Returns a list of font, style, and color of a given string
		<< X-MMS-IM-Format: FN=MS%20Sans%20Serif; EF=; CO=0; PF=0; RL=0
		>> ['Ms Sans Serif', '', '0']
		"""
		format = format.split(" ")
		font = urllib.unquote(format[1].split("FN=")[1][:-1]) #Remove the ;
		color = format[3].split("CO=")[1][:-1]
		color = color.zfill(6)
		r = color[4:]
		g = color[2:4]
		b = color[:2]
		color = "#"+r+g+b
		style = format[2].split("EF=")[1][:-1]
	
		return [font, style, color]

	def close_chat(self):
		self.running = 0
		self.socket.send('OUT\r\n')
		self.socket.close()
		

	def check_dp(self):
		if self.user.msn_object is not None:
			d_p = dp.Base("momsn@live.com", self.user, self)
			d_p.invitation()			

		
